import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { CustomException, ErrorCode } from '@/common/exceptions/custom.exception';
import { RedisService } from '@/shared/redis.service';

@Injectable()
export class PermissionsGuard implements CanActivate {
  constructor(
    private reflector: Reflector,
    private redisService: RedisService,
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const requiredPermissionNames = this.reflector.get<string[]>('permissions', context.getHandler());
    if (!requiredPermissionNames || requiredPermissionNames.length === 0) {
      return true;
    }

    // 从redis中获取系统api权限
    const apiPermissionsFromRedis = await this.redisService.get('SYSTEM_PERMISSIONS');
    const parsedSystemPermissions = JSON.parse(apiPermissionsFromRedis) || [];
    const allRequiredPermissionsExistInSystem = requiredPermissionNames.every((permission) =>
      parsedSystemPermissions.includes(permission),
    );
    if (!allRequiredPermissionsExistInSystem) {
      throw new CustomException(ErrorCode.ERR_11006);
    }

    // 获取当前请求对象
    const request = context.switchToHttp().getRequest();
    if (!request.user) {
      throw new CustomException(ErrorCode.ERR_11004);
    }

    // 判断用户是否拥有所有必要的权限
    const userHasAllRequiredPermissions = requiredPermissionNames.every((permission) =>
      request.user.permissionIds.includes(permission),
    );
    if (!userHasAllRequiredPermissions) {
      throw new CustomException(ErrorCode.ERR_11003);
    }

    return true;
  }
}
